7장 배포 자동화 github action


깃허브 액션

이러한 일련의 작업 과정들을 자동화해주는 github의 도구 github action이다

액션은 이벤트(풀 리퀘스트, 푸시 등등) 기반으로 어떤 이벤트가 발생했을 때 특정 명령 혹은 명령집합을 자동으로 실행시킬 수 있음.

예를들면, 브런치에서 코드 push가 일어나면 자동으로 실행될 명령을 지정할 수 있음.
Attachments/Picture/Pasted image 20240302234643.png

  1. 이벤트 : 액션 작업을 실행시키는 특정 이벤트.
  2. 잡 : 단일 환경에서 실행될 명령의 집합
  3. 스텝 : 잡 안에서 실행하게될 명령들을 정의
  4. 액션 : 단일 명령 그 자체
    job이란 독립된 가상 머신 또는 컨테이너에서 돌아가는 하나의 처리 단위를 의미한다.

액션 설정

깃허브에 액션 추가할 수도 있고, 지역 저장소에서 액션 추가해서 반영할 수도 있음.

# This workflow will do a clean install of node dependencies, build
the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Node. js CI

on:
	push:
		branches: [ main ]
	pull_request:
		branches: [ main ]
jobs:
	build:
		runs-on: ubuntu-latest
		steps:
		- uses: actions/checkout@v2
		- name: Use Node. js ${{ matrix.node-version }} uses: actions/setup-node@v1 with:
node-version: ${{ matrix.node-version }}
		- run: npm ci
		- run: npm run build --if-present
		- run: npm test

코드 수정후 작업 자동화 설정해보기

  1. 테스트 파일 작성
  2. 작업 자동화를 위한 킷허브 액션 설정 파일 작성
  3. 깃허브 원격 저장소에서 작업 자동화 결과 확인
npm install mocha

mocha 설치해주고, 테스트파일 작성

describe('Default Test Set', ()=>{
	it('test1 should be passed', ()=>{
		console.log('test passed')
	});

	it('test2 should be passed', ()=>{
		console.log('test2 passed')
	});
});

mocha 이용해서 테스트파일 실행

./node_modues/.bin/mocha test.spec.js

pakage.json 파일에 test명령어 추가

{
  "name": "mastering-git-github",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www",
    "test": "./node_modules/.bin/mocha test.spec.js"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "express": "^4.18.2",
    "mocha": "^10.2.0",
    "morgan": "~1.9.1"
  }
}

깃허브 액션 파일 생성

mkdir .github
mkdir .github/workflows
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Build

on:
  push:
    branches: ["main"]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm install
      - run: npm test

git add,commit,push 해서 github의 actions 탭에서 정상적으로 작동한 모습을 확인할 수 있다.

배포 자동화 설정하기

자동화 이용해서 배포 자동으로 실행하기

AWS ECS 에 배포하기

AWS ECS 는 AWS 에서 제공하는 컨테이너 관리 서비스
ECS 사용해서 애플리케이션 실행하고 관리할 수 있음.

name: Deploy to Amazon ECS

on:
  push:
    branches: [ "main" ]

env:
  AWS_REGION: MY_AWS_REGION                   # set this to your preferred AWS region, e.g. us-west-1
  ECR_REPOSITORY: MY_ECR_REPOSITORY           # set this to your Amazon ECR repository name
  ECS_SERVICE: MY_ECS_SERVICE                 # set this to your Amazon ECS service name
  ECS_CLUSTER: MY_ECS_CLUSTER                 # set this to your Amazon ECS cluster name
  ECS_TASK_DEFINITION: MY_ECS_TASK_DEFINITION # set this to the path to your Amazon ECS task definition
                                               # file, e.g. .aws/task-definition.json
  CONTAINER_NAME: MY_CONTAINER_NAME           # set this to the name of the container in the
                                               # containerDefinitions section of your task definition

permissions:
  contents: read

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    environment: production

    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Build, tag, and push image to Amazon ECR
      id: build-image
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        IMAGE_TAG: ${{ github.sha }}
      run: |
        # Build a docker container and
        # push it to ECR so that it can
        # be deployed to ECS.
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

    - name: Fill in the new image ID in the Amazon ECS task definition
      id: task-def
      uses: aws-actions/amazon-ecs-render-task-definition@v1
      with:
        task-definition: ${{ env.ECS_TASK_DEFINITION }}
        container-name: ${{ env.CONTAINER_NAME }}
        image: ${{ steps.build-image.outputs.image }}

    - name: Deploy Amazon ECS task definition
      uses: aws-actions/amazon-ecs-deploy-task-definition@v1
      with:
        task-definition: ${{ steps.task-def.outputs.task-definition }}
        service: ${{ env.ECS_SERVICE }}
        cluster: ${{ env.ECS_CLUSTER }}
        wait-for-service-stability: true

Azure App service에 배포하기

Azure App service는 애저에서 제공하는 애플리케이션 배포 및 관리 서비스로 인프라를 직접 관리하지 않아도 된다.

on:
  push:
    branches: [ "main" ]
  workflow_dispatch:

env:
  AZURE_WEBAPP_NAME: your-app-name    # set this to your application's name
  AZURE_WEBAPP_PACKAGE_PATH: '.'      # set this to the path to your web app project, defaults to the repository root
  NODE_VERSION: '14.x'                # set this to the node version to use

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Set up Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ env.NODE_VERSION }}
        cache: 'npm'

    - name: npm install, build, and test
      run: |
        npm install
        npm run build --if-present
        npm run test --if-present

    - name: Upload artifact for deployment job
      uses: actions/upload-artifact@v3
      with:
        name: node-app
        path: .

  deploy:
    permissions:
      contents: none
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Development'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
    - name: Download artifact from build job
      uses: actions/download-artifact@v3
      with:
        name: node-app

    - name: 'Deploy to Azure WebApp'
      id: deploy-to-webapp
      uses: azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}